#pragma once

typedef void* (*lpFnConstructor)();

class CObject
{
private:
    static std::map<std::string, lpFnConstructor>& GetConstructorMap()
    {
        static std::map<std::string, lpFnConstructor> Inst;
        return Inst;
    }

public:
    static void RegisterClass(std::string strName, lpFnConstructor construct)
    { 
        GetConstructorMap()[strName] = construct; 
    }

    static void* CreateObject(const std::string strName)
    {
        lpFnConstructor lpConstructor = nullptr;

        if (GetConstructorMap().find(strName) != GetConstructorMap().end())
            lpConstructor = GetConstructorMap().find(strName)->second;

        if (!lpConstructor)
            return nullptr;
        else
            return (*lpConstructor)();
    }

};

#define REGISTER_CLASS(class_name)  \
class class##class_name\
{\
public:\
    class##class_name() { CObject::RegisterClass(#class_name, class##class_name::CreateObject); } \
    static void* CreateObject() { return new class_name; }\
};\
static class##class_name class##class_name_;
